package ui.units {
	import flash.geom.Point;
	
	import globals.Global;
	import globals.Setting;
	
	import util.GeomUtil;

	public class UnitsManager {
		
		private var buildingList:Array;//建筑物
		private var towerList:Array;//防御塔
		private var monsterList:Array;//怪物
		private var effectList:Array;//效果
		private var bulletList:Array;//子弹

		public function UnitsManager() {
			buildingList = new Array();
			towerList = new Array();
			monsterList = new Array();
			effectList = new Array();
			bulletList = new Array();
		}
		
		public function addTower(unitBean:UnitBean):void {
			var tower:Tower = new Tower();
			tower.init(unitBean);
			tower.id = unitBean.id;
			tower.x = unitBean.x;
			tower.y = unitBean.y;
			tower.repeat = unitBean.repeat;
			Global.game.unitLayer.addChild(tower);
			towerList.push(tower);
		}
		
		public function addMonster(unitBean:UnitBean):void {
			var monster:Monster = new Monster();
			monster.init(unitBean);
			monster.id = unitBean.id;
			monster.x = unitBean.x;
			monster.y = unitBean.y;
			monster.speed = unitBean.speed;
			monster.repeat = unitBean.repeat;
			monster.path = Global.mapManager.getPath();
			Global.game.unitLayer.addChildAt(monster, 1);
			monsterList.push(monster);
		}
		
		public function addMagic(unitBean:UnitBean):void {
			var magic:Magic = new Magic();
			magic.init(unitBean);
			magic.id = unitBean.id;
			magic.x = unitBean.x;
			magic.y = unitBean.y;
			magic.speed = unitBean.speed;
			magic.start = unitBean.start;
			magic.end = unitBean.end;
			magic.target = unitBean.target;
			magic.repeat = unitBean.repeat;
			Global.game.unitLayer.addChild(magic);
			effectList.push(magic);
		}
		
		public function addBullet(unitBean:UnitBean):void {
			var bullet:Bullet = new Bullet();
			bullet.init(unitBean);
			bullet.id = unitBean.id;
			bullet.x = unitBean.x;
			bullet.y = unitBean.y;
			bullet.speed = unitBean.speed;
			bullet.start = unitBean.start;
			bullet.target = unitBean.target as Monster;
			Global.game.unitLayer.addChild(bullet);
			bulletList.push(bullet);
		}
		
		public function removeMagic(id:String):void {
			var effect:Magic;
			for (var i:int = 0; i<effectList.length; i++) {
				effect = effectList[i];
				if (effect.id == id) {
					Global.game.unitLayer.removeChild(effect);
					effectList.splice(i, 1);
					break;
				}
			}
		}
		
		public function removeBullet(id:String):void {
			var bullet:Bullet;
			for (var i:int = 0; i<bulletList.length; i++) {
				bullet = bulletList[i];
				if (bullet.id == id) {
					Global.game.unitLayer.removeChild(bullet);
					bulletList.splice(i, 1);
					break;
				}
			}
		}
		
		public function removeMonster(id:String):void {
			var monster:Monster;
			for (var i:int = 0; i<monsterList.length; i++) {
				monster = monsterList[i];
				if (monster.id == id) {
					Global.game.unitLayer.removeChild(monster);
					monsterList.splice(i, 1);
					break;
				}
			}
		}
		
		public function addTest():void {
			addTowerById("tower1", 4, 9);
			addTowerById("tower2", 9, 7);
			addTowerById("tower3", 10, 7);
			
			addBulletTest();
		}
		
		public function addTowerById(id:String, gx:uint, gy:uint):void {
			var towerData:UnitBean = new UnitBean();
			if (id == "tower1") {
				towerData.url = "Tower1";
				towerData.id = "tower1";
				towerData.domain = "tower";
				towerData.damage = 1;
				towerData.speed = 10;
				towerData.range = 200;
				towerData.attackRange = 20;
				towerData.attackCD = 600;
				towerData.bulletId = "Bullet1";
			} else if (id == "tower2") {
				towerData.url = "Tower2";
				towerData.id = "tower1";
				towerData.domain = "tower";
				towerData.damage = 10;
				towerData.attackCD = 1000;
				towerData.range = 150;
				towerData.speed = 4;
				towerData.attackRange = 20;
				towerData.bulletId = "Bullet2";
			} else if (id == "tower3") {
				towerData.url = "Tower3";
				towerData.id = "tower1";
				towerData.domain = "tower";
				towerData.damage = 50;
				towerData.attackCD = 2000;
				towerData.speed = 2;
				towerData.attackRange = 40;
				towerData.range = 300;
				towerData.bulletId = "Bullet3";
			}
			towerData.x = (gx + 0.5 ) * Setting.TILE_WIDTH;
			towerData.y = (gy + 0.5 ) * Setting.TILE_HEIGHT;
			addTower(towerData);
		}
		
		public function addMonsterTest(id:uint = 1):void {
			var mData:UnitBean = new UnitBean();
			mData.url = "Monster1";
			mData.id = "monster" + id;
			mData.domain = "monster";
			mData.speed = 1;
			mData.life = 100;
			var path:Array = Global.mapManager.getPath()[0];
			mData.x = path[0] * 40 - 20;
			mData.y = path[1] * 40 + 20;
			addMonster(mData);
		}
		
		public function addBulletTest():void {
			var bullerData:UnitBean = new UnitBean();
			bullerData.url = "Bullet1";
			bullerData.id = "bullet1";
			bullerData.domain = "tower";
			var start:Point = new Point(60, 360);
			var monster:Monster = getMonster("monster1");
			if (monster != null) {
				var end:Point = new Point(monster.x, monster.y);
				bullerData.x = start.x;
				bullerData.y = start.y;
				bullerData.start = start;
				bullerData.end = end;
				bullerData.speed = 20;
				bullerData.target = getMonster("monster1");
				addBullet(bullerData);
			}
		}
		
		public function fireBullet(bullerData:UnitBean, monster:Monster):void {
			bullerData.x = bullerData.start.x;
			bullerData.y = bullerData.start.y;
			bullerData.speed = bullerData.speed;
			bullerData.target = monster;
			bullerData.domain = "tower";
			addBullet(bullerData);
		}
		
		public function addMagicTest(from:Point, to:Point):void {
			var magicData:UnitBean = new UnitBean();
			magicData.id = "magic1";
			magicData.url = "flag";
			magicData.start = from;
			magicData.x = from.x;
			magicData.y = from.y;
			magicData.speed = 5;
		}
		
		public function getMonsterByRange(x:Number, y:Number, range:Number):Monster {
			for each (var monster:Monster in monsterList) {
				if (GeomUtil.distance2(monster.x, monster.y, x, y) < range * range && monster.state != UnitState.DEAD) {
					return monster;
				}
			}
			return null;
		}
		
		public function isMonsterInRange(x:Number, y:Number, range:Number, monster:Monster):Boolean {
			return GeomUtil.distance2(monster.x, monster.y, x, y) < range * range;
		}
		
		public function getBuildingList():Array {
			return buildingList;
		}
		
		public function getTower(id:String):Tower {
			for each (var tower:Tower in towerList) {
				if (tower.id == id) {
					return tower;
				}
			}
			return null;
		}
		
		public function getMonster(id:String):Monster {
			for each (var monster:Monster in monsterList) {
				if (monster.id == id) {
					return monster;
				}
			}
			return null;
		}
		
		public function getBuilding(id:String):Building {
			for each (var uint:Building in buildingList) {
				if (uint.id == id) {
					return uint;
				}
			}
			return null;
		}
		
		public function update():void {
			for each (var tower:Tower in towerList) {
				tower.update();
			}
			for each (var monster:Monster in monsterList) {
				monster.update();
			}
			for each (var effect:BaseUnit in effectList) {
				effect.update();
			}
			for each (var bullet:Bullet in bulletList) {
				bullet.update();
			}
		}
	}
}